/* 
 * File:   XmlFileReader.cpp
 * Author: adriano
 * 
 * Created on October 3, 2012, 6:21 PM
 */

#include "XmlFileReader.h"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

XmlFileReader::XmlFileReader() 
{}

XmlFileReader::XmlFileReader(const XmlFileReader& orig) 
{}

XmlFileReader::~XmlFileReader() 
{}

SimulationSetup* XmlFileReader::GetSetup(const std::string& sourceXmlFile)
{
    using boost::property_tree::ptree;
    using boost::property_tree::xml_parser::read_xml;
    
    ptree pt;
    
    read_xml(sourceXmlFile, pt);
    
    int dimension = atoi(pt.get_child("setup.<xmlattr>.dimension").data().c_str());    
            
    SimulationSetup* setup = new SimulationSetup();  
    setup->SetDimension(dimension);
    setup->SetDomain(GetDomain(pt));
    setup->SetSource(GetSource(pt));
    setup->SetField(getField(pt));
           
    return setup;
}

ComputacionalDomain* XmlFileReader::GetDomain(boost::property_tree::ptree& treeContent)
{
    ComputacionalDomain* domain = new ComputacionalDomain();
    
    domain->SetCoordXInitial(atof(treeContent.get_child("setup.domain.xi").data().c_str())); 
    domain->SetCoordXFinal(atof(treeContent.get_child("setup.domain.xf").data().c_str())); 
    domain->SetCoordYInitial(atof(treeContent.get_child("setup.domain.yi").data().c_str())); 
    domain->SetCoordYFinal(atof(treeContent.get_child("setup.domain.yf").data().c_str())); 
    domain->SetCoordZInitial(atof(treeContent.get_child("setup.domain.zi").data().c_str())); 
    domain->SetCoordZFinal(atof(treeContent.get_child("setup.domain.zf").data().c_str()));    
    domain->SetXExtension(atof(treeContent.get_child("setup.domain.x_extension").data().c_str()));
    domain->SetYExtension(atof(treeContent.get_child("setup.domain.y_extension").data().c_str()));
    domain->SetZExtension(atof(treeContent.get_child("setup.domain.z_extension").data().c_str()));
    domain->SetPmlThickness(atof(treeContent.get_child("setup.domain.pml_thickness").data().c_str()));
    domain->SetResolution(atof(treeContent.get_child("setup.domain.resolution").data().c_str()));
    
    return domain;
}

Source* XmlFileReader::GetSource(boost::property_tree::ptree& treeContent)
{      
    Source* source = new Source();
    
    source->SetType(treeContent.get_child("setup.source.type").data());
    source->SetFrequency(atof(treeContent.get_child("setup.source.frequency").data().c_str()));
    source->SetWidth(atof(treeContent.get_child("setup.source.width").data().c_str()));
    source->SetStartTime(atoi(treeContent.get_child("setup.source.start_time").data().c_str()));
    source->SetEndTime(atoi(treeContent.get_child("setup.source.end_time").data().c_str()));    
    
    double* position = new (nothrow) double[3];      
    position[0] = atof(treeContent.get_child("setup.source.source_position.x").data().c_str());
    position[1] = atof(treeContent.get_child("setup.source.source_position.y").data().c_str());
    position[2] = atof(treeContent.get_child("setup.source.source_position.z").data().c_str());
    
    source->SetPosition(position);
    
    return source;
}

SembrField* XmlFileReader::getField(boost::property_tree::ptree& treeContent)
{
    double* initialPosition = new (nothrow) double[3];
    
    initialPosition[0] = atof(treeContent.get_child("setup.field.xi").data().c_str());
    initialPosition[1] = atof(treeContent.get_child("setup.field.yi").data().c_str());
    initialPosition[2] = atof(treeContent.get_child("setup.field.zi").data().c_str());
    
    double* finalPosition = new (nothrow) double[3];
    
    finalPosition[0] = atof(treeContent.get_child("setup.field.xf").data().c_str());
    finalPosition[1] = atof(treeContent.get_child("setup.field.yf").data().c_str());
    finalPosition[2] = atof(treeContent.get_child("setup.field.zf").data().c_str());
    
    SembrField* field = new SembrField();
    
    field->SetFieldType(treeContent.get_child("setup.field.type").data());
    field->SetDirection(treeContent.get_child("setup.field.direction").data());
    field->SetInitialPosition(initialPosition);
    field->SetFinalPosition(finalPosition);
    
    return field;
}

ProjectSettings* XmlFileReader::getProjectSettings(const std::string& sourceXmlFile)
{
    using boost::property_tree::ptree;
    using boost::property_tree::xml_parser::read_xml;
    
    ptree pt;
    
    read_xml(sourceXmlFile, pt);
       
    ProjectSettings* projectSettings = new ProjectSettings();
    projectSettings->SetProjectDirectory(pt.get_child("project_settings.project_directory").data());
    
    std::string isMovie2D = pt.get_child("project_settings.is_movie2d").data().c_str();
    std::string isMovie3D = pt.get_child("project_settings.is_movie3d").data().c_str();
    //std::string isFieldFixedTime = pt.get_child("project_settings.is _fixed_field").data().c_str();
    
    if (isMovie2D == "true")
    {
        projectSettings->SetIsMovie2D(true);
        projectSettings->SetIsFieldAtFixedTime(false);
    }
    else if (isMovie3D == "true")
    {
        projectSettings->SetIsMovie3D(true);
        projectSettings->SetIsFieldAtFixedTime(false);
    }
    else
    {
        projectSettings->SetIsFieldAtFixedTime(true);
        projectSettings->SetIsMovie2D(false);
        projectSettings->SetIsMovie3D(false);
    }
    
    return projectSettings;
}
